// Copyright (c) Lawrence Livermore National Security, LLC and other VisIt
// Project developers.  See the top-level LICENSE file for dates and other
// details.  No copyright assignment is required to contribute to VisIt.

#include "QvisResampleWindow.h"

#include <ResampleAttributes.h>

#include <QCheckBox>
#include <QLabel>
#include <QLayout>
#include <QLineEdit>
#include <QButtonGroup>
#include <QRadioButton>
#include <QvisVariableButton.h>


// ****************************************************************************
// Method: QvisResampleWindow::QvisResampleWindow
//
// Purpose: 
//   Constructor
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

QvisResampleWindow::QvisResampleWindow(const int type,
                         ResampleAttributes *subj,
                         const QString &caption,
                         const QString &shortName,
                         QvisNotepadArea *notepad)
    : QvisOperatorWindow(type,subj, caption, shortName, notepad)
{
    atts = subj;
}


// ****************************************************************************
// Method: QvisResampleWindow::~QvisResampleWindow
//
// Purpose: 
//   Destructor
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

QvisResampleWindow::~QvisResampleWindow()
{
}


// ****************************************************************************
// Method: QvisResampleWindow::CreateWindowContents
//
// Purpose: 
//   Creates the widgets for the window.
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   Cyrus Harrison, Tue Aug 19 16:04:51 PDT 2008
//   Qt4 Port - Autogen +  changed useExtents & distributedResample checkboxs 
//   to span two cols in the layout.
//
//    Kathleen Biagas, Tue Apr 18 16:34:41 PDT 2023
//    Support Qt6: buttonClicked -> idClicked.
//
// ****************************************************************************

void
QvisResampleWindow::CreateWindowContents()
{
    QGridLayout *mainLayout = new QGridLayout(0);
    topLayout->addLayout(mainLayout);

    useExtents = new QCheckBox(tr("Resample Entire Extents"), central);
    connect(useExtents, SIGNAL(toggled(bool)),
            this, SLOT(useExtentsChanged(bool)));
    mainLayout->addWidget(useExtents, 0,0,1,2);

    startXLabel = new QLabel(tr("Start X"), central);
    mainLayout->addWidget(startXLabel,1,0);
    startX = new QLineEdit(central);
    connect(startX, SIGNAL(returnPressed()),
            this, SLOT(startXProcessText()));
    mainLayout->addWidget(startX, 1,1);

    endXLabel = new QLabel(tr("End X"), central);
    mainLayout->addWidget(endXLabel,2,0);
    endX = new QLineEdit(central);
    connect(endX, SIGNAL(returnPressed()),
            this, SLOT(endXProcessText()));
    mainLayout->addWidget(endX, 2,1);

    samplesXLabel = new QLabel(tr("Samples in X"), central);
    mainLayout->addWidget(samplesXLabel,3,0);
    samplesX = new QLineEdit(central);
    connect(samplesX, SIGNAL(returnPressed()),
            this, SLOT(samplesXProcessText()));
    mainLayout->addWidget(samplesX, 3,1);

    startYLabel = new QLabel(tr("Start Y"), central);
    mainLayout->addWidget(startYLabel,4,0);
    startY = new QLineEdit(central);
    connect(startY, SIGNAL(returnPressed()),
            this, SLOT(startYProcessText()));
    mainLayout->addWidget(startY, 4,1);

    endYLabel = new QLabel(tr("End Y"), central);
    mainLayout->addWidget(endYLabel,5,0);
    endY = new QLineEdit(central);
    connect(endY, SIGNAL(returnPressed()),
            this, SLOT(endYProcessText()));
    mainLayout->addWidget(endY, 5,1);

    samplesYLabel = new QLabel(tr("Samples in Y"), central);
    mainLayout->addWidget(samplesYLabel,6,0);
    samplesY = new QLineEdit(central);
    connect(samplesY, SIGNAL(returnPressed()),
            this, SLOT(samplesYProcessText()));
    mainLayout->addWidget(samplesY, 6,1);

    is3D = new QCheckBox(tr("3D resampling"), central);
    connect(is3D, SIGNAL(toggled(bool)),
            this, SLOT(is3DChanged(bool)));
    mainLayout->addWidget(is3D, 7,0);

    startZLabel = new QLabel(tr("Start Z"), central);
    mainLayout->addWidget(startZLabel,8,0);
    startZ = new QLineEdit(central);
    connect(startZ, SIGNAL(returnPressed()),
            this, SLOT(startZProcessText()));
    mainLayout->addWidget(startZ, 8,1);

    endZLabel = new QLabel(tr("End Z"), central);
    mainLayout->addWidget(endZLabel,9,0);
    endZ = new QLineEdit(central);
    connect(endZ, SIGNAL(returnPressed()),
            this, SLOT(endZProcessText()));
    mainLayout->addWidget(endZ, 9,1);

    samplesZLabel = new QLabel(tr("Samples in Z"), central);
    mainLayout->addWidget(samplesZLabel,10,0);
    samplesZ = new QLineEdit(central);
    connect(samplesZ, SIGNAL(returnPressed()),
            this, SLOT(samplesZProcessText()));
    mainLayout->addWidget(samplesZ, 10,1);

    tieResolverLabel = new QLabel(tr("Resolve ties"), central);
    mainLayout->addWidget(tieResolverLabel,11,0);
    QWidget *tieResolverWidget = new QWidget(central);
    tieResolver = new QButtonGroup(tieResolverWidget);
    QHBoxLayout *tieResolverLayout = new QHBoxLayout(tieResolverWidget);
    tieResolverLayout->setContentsMargins(0,0,0,0);
    tieResolverLayout->setSpacing(10);
    QRadioButton *tieResolverTieResolverrandom = new QRadioButton(tr("random"), tieResolverWidget);
    tieResolver->addButton(tieResolverTieResolverrandom,0);
    tieResolverLayout->addWidget(tieResolverTieResolverrandom);
    QRadioButton *tieResolverTieResolverlargest = new QRadioButton(tr("largest"), tieResolverWidget);
    tieResolver->addButton(tieResolverTieResolverlargest,1);
    tieResolverLayout->addWidget(tieResolverTieResolverlargest);
    QRadioButton *tieResolverTieResolversmallest = new QRadioButton(tr("smallest"), tieResolverWidget);
    tieResolver->addButton(tieResolverTieResolversmallest,2);
    tieResolverLayout->addWidget(tieResolverTieResolversmallest);
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
    connect(tieResolver, SIGNAL(buttonClicked(int)),
            this, SLOT(tieResolverChanged(int)));
#else
    connect(tieResolver, SIGNAL(idClicked(int)),
            this, SLOT(tieResolverChanged(int)));
#endif
    mainLayout->addWidget(tieResolverWidget, 11,1);

    tieResolverVariableLabel = new QLabel(tr("Variable to resolve ties"), central);
    mainLayout->addWidget(tieResolverVariableLabel,12,0);
    int tieResolverVariableMask = QvisVariableButton::Scalars;
    tieResolverVariable = new QvisVariableButton(true, true, true, tieResolverVariableMask, central);
    tieResolverVariable->setDefaultVariable("default");
    connect(tieResolverVariable, SIGNAL(activated(const QString&)),
            this, SLOT(tieResolverVariableChanged(const QString&)));
    mainLayout->addWidget(tieResolverVariable, 12,1);

    defaultValueLabel = new QLabel(tr("Value for uncovered regions"), central);
    mainLayout->addWidget(defaultValueLabel,13,0);
    defaultValue = new QLineEdit(central);
    connect(defaultValue, SIGNAL(returnPressed()),
            this, SLOT(defaultValueProcessText()));
    mainLayout->addWidget(defaultValue, 13,1);

    distributedResample = new QCheckBox(tr("Distribute resampled data set across all processors (parallel only)?"), central);
    connect(distributedResample, SIGNAL(toggled(bool)),
            this, SLOT(distributedResampleChanged(bool)));
    mainLayout->addWidget(distributedResample, 14,0,1,2);

    cellCenteredOutput = new QCheckBox(tr("Make output cell centered"), central);
    connect(cellCenteredOutput, SIGNAL(toggled(bool)),
            this, SLOT(cellCenteredOutputChanged(bool)));
    mainLayout->addWidget(cellCenteredOutput, 15,0,1,2);
}


// ****************************************************************************
// Method: QvisResampleWindow::UpdateWindow
//
// Purpose: 
//   Updates the widgets in the window when the subject changes.
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   Cyrus Harrison, Tue Aug 19 16:04:51 PDT 2008
//   Qt4 Port - Added extra disable case for useExtents & startZ/endZ.
//
// ****************************************************************************

void
QvisResampleWindow::UpdateWindow(bool doAll)
{

    for(int i = 0; i < atts->NumAttributes(); ++i)
    {
        if(!doAll)
        {
            if(!atts->IsSelected(i))
            {
                continue;
            }
        }

        switch(i)
        {
          case ResampleAttributes::ID_useExtents:
            if (atts->GetUseExtents() == false)
            {
                startX->setEnabled(true);
                if(startXLabel)
                    startXLabel->setEnabled(true);
            }
            else
            {
                startX->setEnabled(false);
                if(startXLabel)
                    startXLabel->setEnabled(false);
            }
            if (atts->GetUseExtents() == false)
            {
                endX->setEnabled(true);
                if(endXLabel)
                    endXLabel->setEnabled(true);
            }
            else
            {
                endX->setEnabled(false);
                if(endXLabel)
                    endXLabel->setEnabled(false);
            }
            if (atts->GetUseExtents() == false)
            {
                startY->setEnabled(true);
                if(startYLabel)
                    startYLabel->setEnabled(true);
            }
            else
            {
                startY->setEnabled(false);
                if(startYLabel)
                    startYLabel->setEnabled(false);
            }
            if (atts->GetUseExtents() == false)
            {
                endY->setEnabled(true);
                if(endYLabel)
                    endYLabel->setEnabled(true);
            }
            else
            {
                endY->setEnabled(false);
                if(endYLabel)
                    endYLabel->setEnabled(false);
            }
            if (atts->GetUseExtents() == false && atts->GetIs3D() == true)
            {
                startZ->setEnabled(true);
                if(startZLabel)
                    startZLabel->setEnabled(true);
            }
            else
            {
                startZ->setEnabled(false);
                if(startZLabel)
                    startZLabel->setEnabled(false);
            }
            if (atts->GetUseExtents() == false && atts->GetIs3D() == true)
            {
                endZ->setEnabled(true);
                if(endZLabel)
                    endZLabel->setEnabled(true);
            }
            else
            {
                endZ->setEnabled(false);
                if(endZLabel)
                    endZLabel->setEnabled(false);
            }
            useExtents->blockSignals(true);
            useExtents->setChecked(atts->GetUseExtents());
            useExtents->blockSignals(false);
            break;
          case ResampleAttributes::ID_startX:
            startX->setText(DoubleToQString(atts->GetStartX()));
            break;
          case ResampleAttributes::ID_endX:
            endX->setText(DoubleToQString(atts->GetEndX()));
            break;
          case ResampleAttributes::ID_samplesX:
            samplesX->setText(IntToQString(atts->GetSamplesX()));
            break;
          case ResampleAttributes::ID_startY:
            startY->setText(DoubleToQString(atts->GetStartY()));
            break;
          case ResampleAttributes::ID_endY:
            endY->setText(DoubleToQString(atts->GetEndY()));
            break;
          case ResampleAttributes::ID_samplesY:
            samplesY->setText(IntToQString(atts->GetSamplesY()));
            break;
          case ResampleAttributes::ID_is3D:
            if (atts->GetIs3D() == true && atts->GetUseExtents() == false)
            {
                startZ->setEnabled(true);
                if(startZLabel)
                    startZLabel->setEnabled(true);
            }
            else
            {
                startZ->setEnabled(false);
                if(startZLabel)
                    startZLabel->setEnabled(false);
            }
            if (atts->GetIs3D() == true && atts->GetUseExtents() == false)
            {
                endZ->setEnabled(true);
                if(endZLabel)
                    endZLabel->setEnabled(true);
            }
            else
            {
                endZ->setEnabled(false);
                if(endZLabel)
                    endZLabel->setEnabled(false);
            }
            if (atts->GetIs3D() == true)
            {
                samplesZ->setEnabled(true);
                if(samplesZLabel)
                    samplesZLabel->setEnabled(true);
            }
            else
            {
                samplesZ->setEnabled(false);
                if(samplesZLabel)
                    samplesZLabel->setEnabled(false);
            }
            is3D->blockSignals(true);
            is3D->setChecked(atts->GetIs3D());
            is3D->blockSignals(false);
            break;
          case ResampleAttributes::ID_startZ:
            startZ->setText(DoubleToQString(atts->GetStartZ()));
            break;
          case ResampleAttributes::ID_endZ:
            endZ->setText(DoubleToQString(atts->GetEndZ()));
            break;
          case ResampleAttributes::ID_samplesZ:
            samplesZ->setText(IntToQString(atts->GetSamplesZ()));
            break;
          case ResampleAttributes::ID_tieResolver:
            if (atts->GetTieResolver() == ResampleAttributes::smallest || atts->GetTieResolver() == ResampleAttributes::largest)
            {
                tieResolverVariable->setEnabled(true);
                if(tieResolverVariableLabel)
                    tieResolverVariableLabel->setEnabled(true);
            }
            else
            {
                tieResolverVariable->setEnabled(false);
                if(tieResolverVariableLabel)
                    tieResolverVariableLabel->setEnabled(false);
            }
            tieResolver->blockSignals(true);
            if(tieResolver->button((int)atts->GetTieResolver()) != 0)
                tieResolver->button((int)atts->GetTieResolver())->setChecked(true);
            tieResolver->blockSignals(false);
            break;
          case ResampleAttributes::ID_tieResolverVariable:
            tieResolverVariable->blockSignals(true);
            tieResolverVariable->setText(QString(atts->GetTieResolverVariable().c_str()));
            tieResolverVariable->blockSignals(false);
            break;
          case ResampleAttributes::ID_defaultValue:
            defaultValue->setText(DoubleToQString(atts->GetDefaultValue()));
            break;
          case ResampleAttributes::ID_distributedResample:
            distributedResample->blockSignals(true);
            distributedResample->setChecked(atts->GetDistributedResample());
            distributedResample->blockSignals(false);
            break;
          case ResampleAttributes::ID_cellCenteredOutput:
            cellCenteredOutput->blockSignals(true);
            cellCenteredOutput->setChecked(atts->GetCellCenteredOutput());
            cellCenteredOutput->blockSignals(false);
            break;
        }
    }
}


// ****************************************************************************
// Method: QvisResampleWindow::GetCurrentValues
//
// Purpose: 
//   Gets values from certain widgets and stores them in the subject.
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   Cyrus Harrison, Thu Aug 21 16:34:45 PDT 2008
//   Qt4 Port. Make sure not to set any of the start/end atts if useExtents
//   is true. 
//   
// ****************************************************************************

void
QvisResampleWindow::GetCurrentValues(int which_widget)
{
    bool doAll = (which_widget == -1);

    // Do startX
    if(atts->GetUseExtents() == false && 
       (which_widget == ResampleAttributes::ID_startX || doAll))
    {
        double val;
        if(LineEditGetDouble(startX, val))
            atts->SetStartX(val);
        else
        {
            ResettingError(tr("Start X"),
                DoubleToQString(atts->GetStartX()));
            atts->SetStartX(atts->GetStartX());
        }
    }

    // Do endX
    if(atts->GetUseExtents() == false && 
      (which_widget == ResampleAttributes::ID_endX || doAll))
    {
        double val;
        if(LineEditGetDouble(endX, val))
            atts->SetEndX(val);
        else
        {
            ResettingError(tr("End X"),
                DoubleToQString(atts->GetEndX()));
            atts->SetEndX(atts->GetEndX());
        }
    }

    // Do samplesX
    if(which_widget == ResampleAttributes::ID_samplesX || doAll)
    {
        int val;
        if(LineEditGetInt(samplesX, val))
            atts->SetSamplesX(val);
        else
        {
            ResettingError(tr("Samples in X"),
                IntToQString(atts->GetSamplesX()));
            atts->SetSamplesX(atts->GetSamplesX());
        }
    }

    // Do startY
    if(atts->GetUseExtents() == false && 
       (which_widget == ResampleAttributes::ID_startY || doAll))
    {
        double val;
        if(LineEditGetDouble(startY, val))
            atts->SetStartY(val);
        else
        {
            ResettingError(tr("Start Y"),
                DoubleToQString(atts->GetStartY()));
            atts->SetStartY(atts->GetStartY());
        }
    }

    // Do endY
    if(atts->GetUseExtents() == false && 
       (which_widget == ResampleAttributes::ID_endY || doAll))
    {
        double val;
        if(LineEditGetDouble(endY, val))
            atts->SetEndY(val);
        else
        {
            ResettingError(tr("End Y"),
                DoubleToQString(atts->GetEndY()));
            atts->SetEndY(atts->GetEndY());
        }
    }

    // Do samplesY
    if(which_widget == ResampleAttributes::ID_samplesY || doAll)
    {
        int val;
        if(LineEditGetInt(samplesY, val))
            atts->SetSamplesY(val);
        else
        {
            ResettingError(tr("Samples in Y"),
                IntToQString(atts->GetSamplesY()));
            atts->SetSamplesY(atts->GetSamplesY());
        }
    }

    // Do startZ
    if(atts->GetUseExtents() == false && 
        (which_widget == ResampleAttributes::ID_startZ || doAll))
    {
        double val;
        if(LineEditGetDouble(startZ, val))
            atts->SetStartZ(val);
        else
        {
            ResettingError(tr("Start Z"),
                DoubleToQString(atts->GetStartZ()));
            atts->SetStartZ(atts->GetStartZ());
        }
    }

    // Do endZ
    if(atts->GetUseExtents() == false && 
       (which_widget == ResampleAttributes::ID_endZ || doAll))
    {
        double val;
        if(LineEditGetDouble(endZ, val))
            atts->SetEndZ(val);
        else
        {
            ResettingError(tr("End Z"),
                DoubleToQString(atts->GetEndZ()));
            atts->SetEndZ(atts->GetEndZ());
        }
    }

    // Do samplesZ
    if(which_widget == ResampleAttributes::ID_samplesZ || doAll)
    {
        int val;
        if(LineEditGetInt(samplesZ, val))
            atts->SetSamplesZ(val);
        else
        {
            ResettingError(tr("Samples in Z"),
                IntToQString(atts->GetSamplesZ()));
            atts->SetSamplesZ(atts->GetSamplesZ());
        }
    }

    // Do defaultValue
    if(which_widget == ResampleAttributes::ID_defaultValue || doAll)
    {
        double val;
        if(LineEditGetDouble(defaultValue, val))
            atts->SetDefaultValue(val);
        else
        {
            ResettingError(tr("Value for uncovered regions"),
                DoubleToQString(atts->GetDefaultValue()));
            atts->SetDefaultValue(atts->GetDefaultValue());
        }
    }

}


//
// Qt Slot functions
//


void
QvisResampleWindow::useExtentsChanged(bool val)
{
    atts->SetUseExtents(val);
    Apply();
}


void
QvisResampleWindow::startXProcessText()
{
    GetCurrentValues(ResampleAttributes::ID_startX);
    Apply();
}


void
QvisResampleWindow::endXProcessText()
{
    GetCurrentValues(ResampleAttributes::ID_endX);
    Apply();
}


void
QvisResampleWindow::samplesXProcessText()
{
    GetCurrentValues(ResampleAttributes::ID_samplesX);
    Apply();
}


void
QvisResampleWindow::startYProcessText()
{
    GetCurrentValues(ResampleAttributes::ID_startY);
    Apply();
}


void
QvisResampleWindow::endYProcessText()
{
    GetCurrentValues(ResampleAttributes::ID_endY);
    Apply();
}


void
QvisResampleWindow::samplesYProcessText()
{
    GetCurrentValues(ResampleAttributes::ID_samplesY);
    Apply();
}


void
QvisResampleWindow::is3DChanged(bool val)
{
    atts->SetIs3D(val);
    Apply();
}


void
QvisResampleWindow::startZProcessText()
{
    GetCurrentValues(ResampleAttributes::ID_startZ);
    Apply();
}


void
QvisResampleWindow::endZProcessText()
{
    GetCurrentValues(ResampleAttributes::ID_endZ);
    Apply();
}


void
QvisResampleWindow::samplesZProcessText()
{
    GetCurrentValues(ResampleAttributes::ID_samplesZ);
    Apply();
}


void
QvisResampleWindow::tieResolverChanged(int val)
{
    if(val != atts->GetTieResolver())
    {
        atts->SetTieResolver(ResampleAttributes::TieResolver(val));
        Apply();
    }
}


void
QvisResampleWindow::tieResolverVariableChanged(const QString &varName)
{
    atts->SetTieResolverVariable(varName.toStdString());
    SetUpdate(false);
    Apply();
}


void
QvisResampleWindow::defaultValueProcessText()
{
    GetCurrentValues(ResampleAttributes::ID_defaultValue);
    Apply();
}


void
QvisResampleWindow::distributedResampleChanged(bool val)
{
    atts->SetDistributedResample(val);
    SetUpdate(false);
    Apply();
}

void
QvisResampleWindow::cellCenteredOutputChanged(bool val)
{
    atts->SetCellCenteredOutput(val);
    Apply();
}
